
const canvas = document.getElementById('source'),
  ctx = canvas.getContext('2d'),
  image = new Image(),
  canvasDes = document.getElementById('result'),
  ctxDes = canvasDes.getContext('2d'),
  imageFilter = new Filter(new AudioContext())

let imgData
let currImgData
let tmpImgData
let wave

image.src = './assets/Lenna.png'
image.onload = function () {
  ctx.drawImage(image, 0, 0, canvas.width, canvas.height)
  ctxDes.drawImage(image, 0, 0, canvas.width, canvas.height)
  imgData = ctx.getImageData(0, 0, canvas.width, canvas.height)
  currImgData = ctx.createImageData(canvas.width, canvas.height)
  tmpImgData = ctx.createImageData(canvas.width, canvas.height)
  for (let i = 0; i < imgData.data.length; i++) {
    currImgData.data[i] = imgData.data[i]
    tmpImgData.data[i] = imgData.data[i]
  }
  wave = drawWave()
}

function filterImage () {
  const type = passform && passform.passtype && passform.passtype.value
  if (!type) return

  const value = passform[type].value
  const splitted = splitRGB(imgData.data)

  Promise.all([
    imageFilter.filterSignal(splitted.red, type, value),
    imageFilter.filterSignal(splitted.green, type, value),
    imageFilter.filterSignal(splitted.blue, type, value)
  ]).then(values => {
    const arr = mountRGB({
      red: values[0],
      green: values[1],
      blue: values[2],
      alpha: splitted.alpha,
      arr: currImgData.data
    })
    tmpImgData.data.set(arr)
    refreshImg()
    plotFiltered(arr, ctxDes)
  }).catch(err => {
    coonsole.error(err)
  })
}

function refreshImg () {
  const red = document.getElementById('red').checked
  const green = document.getElementById('green').checked
  const blue = document.getElementById('blue').checked

  for (let i = 0; i < tmpImgData.data.length; i += 4) {
    const p = tmpImgData.data
    red ? p[i] = currImgData.data[i] : p[i] = 0
    green ? p[i + 1] = currImgData.data[i + 1] : p[i + 1] = 0
    blue ? p[i + 2] = currImgData.data[i + 2] : p[i + 2] = 0
    p[i + 3] = currImgData.data[i + 3]
  }

  ctxDes.clearRect(0, 0, ctxDes.canvas.width, ctxDes.canvas.height)
  ctxDes.putImageData(tmpImgData, 0, 0)

  if (wave) wave.refresh()
}

function drawWave () {
  const data = tmpImgData.data
  const length = tmpImgData.width * tmpImgData.height
  const imgWidth = tmpImgData.width

  const wvcanvas = document.getElementById('wave')
  const context = wvcanvas.getContext('2d')

  const height = wvcanvas.height,
    width = wvcanvas.width,
    padding = {
      left: 0,
      right: 0,
      top: 30,
      bottom: 30
    }

  // 比例尺
  const xScale = d3.scaleLinear()
    .domain([0, imgWidth - 1])
    .range([0, width - padding.left - padding.right])
  const xScaler = d3.scaleLinear()
    .domain([0, width - padding.left - padding.right])
    .range([0, imgWidth - 1])
  const yScale = d3.scaleLinear()
    .domain([0, 255])
    .range([height - padding.top - padding.bottom, 0])

  // line生成器
  const line = d3.line()
    .x((d, i) => xScale(i))
    .y(d => yScale(d))

  let start = 0
  let end = imgWidth
  drawSection(line, context, data, start, end, padding)

  function move (delta) {
    const offset = parseInt(xScaler(-delta*2))
    if (start + offset < 0) start = 0
    else start += offset
    end = start + imgWidth
    context.clearRect(0, 0, width, height)
    drawSection(line, context, data, start, end, padding)
  }

  listenMousemove(d3.select(wvcanvas), delta => {
    move(delta)
  })

  return {
    refresh: function () {
      context.clearRect(0, 0, width, height)
      drawSection(line, context, data, start, end, padding)
    }
  }
}
